package cool.mylog.mylog2end.utils;

import cool.mylog.mylog2end.bean.User;
import io.jsonwebtoken.*;
import io.jsonwebtoken.security.Keys;
import jakarta.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;


import javax.crypto.SecretKey;
import java.nio.charset.StandardCharsets;
import java.util.Date;

@Component
public class JwtUtils {

    /**
     * 有效时间：天。从配置文件获取，转为毫秒后赋给静态变量 expiration
     */
    @Value("${jwt.expirationDay}")
    private Integer expirationDay;

    /**
     * 自定义签名，密钥字符串，从配置文件获取，转换后赋给静态变量 secretKey
     */
    @Value("${jwt.secretKeyStr}")
    private String secretKeyStr;

    /**
     * 有效时间：毫秒
     */
    private static long expiration;

    /**
     * 自定义签名，密钥
     */
    private static SecretKey secretKey;

    /**
     * JWT 提供了方便的构建器类，可以为任何给定的密钥生成足够安全的密钥
     */
    // private static final SecretKey secretKey = Jwts.SIG.HS256.key().build();

    /**
     * 解密器
     */
    private static JwtParser parser;

    @PostConstruct
    public void postConstruct() {
        JwtUtils.expiration = this.expirationDay * 1000L * 60 * 60 * 24;
        JwtUtils.secretKey = Keys.hmacShaKeyFor(this.secretKeyStr.getBytes(StandardCharsets.UTF_8));
        JwtUtils.parser = Jwts.parser().verifyWith(secretKey).build();
    }

    /**
     * 加密
     *
     * @param id   用户ID
     * @param name 用户名
     * @return token字符串
     */
    public static String getToken(long id, String name) {
        Date now = new Date();
        JwtBuilder jwtBuilder = Jwts.builder()
                .subject("UserToken") // 主题
                .claim("id", id)
                .claim("name", name)
                .issuedAt(now) // 签发时间：当前
                .expiration(new Date(now.getTime() + expiration)) // 过期时间
                .signWith(secretKey, Jwts.SIG.HS256); // 密钥，加密方式
        return jwtBuilder.compact();
    }

    /**
     * 加密
     *
     * @param user User对象
     * @return token字符串
     */
    public static String getToken(User user) {
        return getToken(user.getId(), user.getName());
    }

    /**
     * 获取头
     *
     * @param token 用户token字符串
     * @return Header对象
     */
    public static Header getHeader(String token) {
        return parser.parse(token).getHeader();
    }

    /**
     * 获取负载
     *
     * @param token 用户token字符串
     * @return 一个对象，但是他的属性是不知道的
     */
    public static Object getPayload(String token) {
        return parser.parse(token).getPayload();
    }

    /**
     * 获取负载
     *
     * @param token 用户token字符串
     * @return 载荷链，用get方法取里面的属性
     */
    public static Claims getClaims(String token) {

        return parser.parseSignedClaims(token).getPayload();
    }

    /**
     * 从token中拿到用户名，如果失败返回空串
     *
     * @param token 用户token字符串
     * @return 用户名
     */
    public static String getName(String token) {
        try {
            return getClaims(token).get("name", String.class);
        } catch (Exception e) {
            return "";
        }
    }

    /**
     * 从token获取用户ID，如果失败返回0
     *
     * @param token 用户token字符串
     * @return 用户ID
     */
    public static Long getId(String token) {
        try {
            return getClaims(token).get("id", Long.class);
        } catch (Exception e) {
            return 0L;
        }
    }
}
